package gcp.principal;

import gcp.Usuario;
import gcp.gui.FrameAmigo;
import gcp.gui.FrameAmigos;
import gcp.gui.FrameColecionaveis;
import gcp.gui.FrameEmprestar;
import gcp.gui.FrameEmprestimos;
import gcp.gui.FrameFilme;
import gcp.gui.FrameGibi;
import gcp.gui.FrameJogo;
import gcp.gui.FrameLogin;
import gcp.gui.FramePegarEmprestado;
import gcp.gui.FrameUsuario;

import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;

import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

/**
 * FrameGCP<br>
 * Frame principal para manipulação dos frame internos do GCP.
 * @author Hildegard Furtado.
 */
public class FrameGCP extends JFrame {

    private static final long serialVersionUID = 1L;

    private GCP gcp;

    private JDesktopPane tela;

    private JMenuBar barraDeMenu;
    private JMenu menuColecao;
    private JMenu menuAmigos;
    private JMenu menuEmprestimo;
    private JMenu menuSistema;
    private JMenuItem menuCadastrarUsuario;
    private JMenuItem menuCadastrarGibi;
    private JMenuItem menuColecoes;
    private JMenuItem menuAmigosDoUsuario;
    private JMenuItem menuCadastrarFilme;
    private JMenuItem menuCadastrarJogo;
    private JMenuItem menuEmprestar;
    private JMenuItem menuEditarPerfil;
    private JMenuItem menuExcluirConta;
    private JMenuItem menuPegarEmprestado;
    private JMenuItem menuCadastrarAmigo;
    private JMenuItem menuEmprestimosDoUsuario;
    private JMenuItem menuSair;

    private Usuario usuarioLogado;

    /**
     * Construtor.
     */
    public FrameGCP() {
        super("GCP - Gerenciador de Coleções Pessoais");
        inicializar();
        acoes();
        constroiMenu();
    }

    /**
     * Inicializa os componentes.
     */
    private void inicializar() {
        setSize(800, 600);
        setExtendedState(Frame.MAXIMIZED_BOTH);

        gcp = GCP.carregarGCP();

        tela = new JDesktopPane();
        setContentPane(tela);
        tela.setLayout(null);

        barraDeMenu = new JMenuBar();
        menuSistema = new JMenu("Sistema");
        menuColecao = new JMenu("Coleção");
        menuAmigos = new JMenu("Amigos");
        menuEmprestimo = new JMenu("Emprestimos");

        menuCadastrarUsuario = new JMenuItem("Cadastrar usuário");
        menuCadastrarGibi = new JMenuItem("Cadastrar gibi");
        menuCadastrarFilme = new JMenuItem("Cadastrar filme");
        menuEmprestar = new JMenuItem("Emprestar");
        menuPegarEmprestado = new JMenuItem("Pegar emprestado");
        menuEmprestimosDoUsuario = new JMenuItem("Empréstimos");
        menuEditarPerfil = new JMenuItem("Editar perfil");
        menuCadastrarJogo = new JMenuItem("Cadastrar jogo");
        menuCadastrarAmigo = new JMenuItem("Cadastrar");
        menuColecoes = new JMenuItem("Coleções");
        menuAmigosDoUsuario = new JMenuItem("Amigos");
        menuSair = new JMenuItem("Sair");
        menuExcluirConta = new JMenuItem("Excluir conta");

        ImageIcon icone = new ImageIcon("gcp.png");
        setIconImage(icone.getImage());

    }

    /**
     * Define as ações dos componentes.
     */
    private void acoes() {
        // Encerra o sistema após clicar no X da janela.
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0) {
                gcp.gravar();
                System.exit(0);
            }

            @Override
            public void windowOpened(WindowEvent arg0) {
                abrirFrameLogin();
            }
        });
        // Encerra o sistema ao clicar em sair.
        menuSair.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                gcp.gravar();
                System.exit(0);
            }
        });
        // Abre o frame para cadastrar empréstimo
        menuEmprestar.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                cadastrarEmprestimo();
            }
        });
        menuPegarEmprestado.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                pegarEmprestado();
            }
        });
        // Abre o frame para cadastrar empréstimo
        menuEmprestimosDoUsuario.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirEmprestimosDoUsuario();
            }
        });
        menuCadastrarUsuario.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirCadastroDeUsuarios();
            }
        });
        menuCadastrarGibi.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirCadastroDeGibi();
            }
        });
        menuCadastrarFilme.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirCadastroDeFilme();
            }
        });
        menuCadastrarJogo.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirCadastroDeJogo();
            }
        });
        menuCadastrarAmigo.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e) {
                abrirCadastroDeAmigo();
            }
        });
        menuColecoes.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent arg0) {
                abrirColecoes();
            }
        });
        menuAmigosDoUsuario.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent arg0) {
                abrirAmigos();
            }
        });
        menuExcluirConta.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                excluirConta();
            }
        });
        menuEditarPerfil.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                editarPerfil();
            }
        });
    }

    /**
     * Edita o perfil do usuairo logado.
     */
    protected void editarPerfil() {
        abrirJanela(new FrameUsuario(this, usuarioLogado));
    }

    /**
     * Excluí a conta do usuário.
     */
    protected void excluirConta() {
        if (confirmar("Excluir conta", "Deseja excluir sua conta do sistema?")){
            try {
                gcp.removerUsuario(usuarioLogado);
                setJMenuBar(null);
                usuarioLogado = null;
                abrirFrameLogin();
            } catch (Exception e) {
                exibirMensagem(e.getMessage());
            }
        }
    }
    
    /**
     * Solicita uma confirmação.
     * @param titulo Titulo da janela de confirmação.
     * @param mensagem Pergunta da mensagem de confirmação.
     * @return true - se confirmado, false - caso contrário.
     */
    public boolean confirmar(String titulo, String mensagem) {
        Object[] options = { "Sim", "Não" };
        int n = JOptionPane.showOptionDialog(this, mensagem, titulo,
                JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
                null, options, options[0]);
        if (n == JOptionPane.YES_OPTION) {
            return true;
        }
        return false;
    }

    /**
     * Abre frame para pegar emprestado.
     */
    protected void pegarEmprestado() {
        abrirJanela(new FramePegarEmprestado(this, null));
    }

    /**
     * Exibe os emprestimos do usuário.
     */
    protected void abrirEmprestimosDoUsuario() {
        abrirJanela(new FrameEmprestimos(this));
    }

    /**
     * Abre o frame para cadastrar empréstimo.
     */
    protected void cadastrarEmprestimo() {
        abrirJanela(new FrameEmprestar(this, null));
    }

    /**
     * Abre o frame de login.
     */
    protected void abrirFrameLogin() {
        abrirJanela(new FrameLogin(this));
    }

    /**
     * Abre o frame de colecoes
     */
    protected void abrirColecoes() {
        abrirJanela(new FrameColecionaveis(this));
    }

    /**
     * Abre a janela para cadastro de usuarios.
     */
    protected void abrirCadastroDeUsuarios() {
        abrirJanela(new FrameUsuario(this, null));
    }

    /**
     * Abre a janela do cadastro de Gibis
     */
    protected void abrirCadastroDeGibi() {
        abrirJanela(new FrameGibi(this, null));
    }

    /**
     * Abre a janela do cadastro de Filmes
     */
    protected void abrirCadastroDeFilme() {
        abrirJanela(new FrameFilme(this, null));
    }

    /**
     * Abre a janela do cadastro de Jogos
     */
    protected void abrirCadastroDeJogo() {
        abrirJanela(new FrameJogo(this, null));
    }

    /**
     * Abre a janela do cadastro de Amigos
     */
    protected void abrirCadastroDeAmigo() {
        abrirJanela(new FrameAmigo(this, null));
    }

    /**
     * Abre o frame com a tabela de Amigos
     */
    protected void abrirAmigos() {
        abrirJanela(new FrameAmigos(this));
    }

    /**
     * Adiciona os itens de menu.
     */
    private void constroiMenu() {
        barraDeMenu.add(menuSistema);
        barraDeMenu.add(menuColecao);
        barraDeMenu.add(menuAmigos);
        barraDeMenu.add(menuEmprestimo);

        menuAmigos.add(menuCadastrarAmigo);
        menuAmigos.addSeparator();
        menuAmigos.add(menuAmigosDoUsuario);
        menuSistema.add(menuCadastrarUsuario);
        menuSistema.add(menuEditarPerfil);
        menuSistema.addSeparator();
        menuSistema.add(menuExcluirConta);
        menuSistema.addSeparator();
        menuSistema.add(menuSair);
        menuColecao.add(menuCadastrarGibi);
        menuColecao.add(menuCadastrarFilme);
        menuColecao.add(menuCadastrarJogo);
        menuColecao.addSeparator();
        menuColecao.add(menuColecoes);

        menuEmprestimo.add(menuEmprestar);
        menuEmprestimo.add(menuPegarEmprestado);
        menuEmprestimo.add(menuEmprestimosDoUsuario);
    }

    /**
     * Abre uma janela dentro do frame atual.
     * @param frame interno a ser aberto.
     */
    public void abrirJanela(JInternalFrame frame) {
        frame.setVisible(true);
        frame.setBounds((getWidth() - frame.getWidth()) / 2, 20, frame
                .getWidth(), frame.getHeight());
        tela.add(frame);
        frame.addInternalFrameListener(new InternalFrameAdapter() {
            
            @Override
            public void internalFrameClosed(InternalFrameEvent e) {
                tela.remove(e.getInternalFrame());
            }
        });
        try {
            frame.setSelected(true);
        } catch (PropertyVetoException e) {}
        rePintar();
    }

    /**
     * Retorna o GCP com o qual o sistema manipulará.
     * @return GCP.
     */
    public GCP getGcp() {
        return gcp;
    }

    /**
     * Realiza a autenticacao do usuario com o GCP, retornando true em caso de
     * sucesso, e false caso contrario.
     * @param login Login do usuario.
     * @param senha Senha do usuario.
     * @return true/false.
     */
    public boolean autenticar(String login, String senha) {
        Usuario usuario = gcp.getUsuario(login);
        if (usuario == null) {
            return false;
        }
        if (usuario.getSenha().equals(senha)) {
            usuarioLogado = usuario;
            setJMenuBar(barraDeMenu);
            rePintar();
            return true;
        }
        return false;
    }

    /**
     * Exibe mensagens para o Usuario
     * @param mensagem Mensagem a ser enviada para o Usuario
     */
    public void exibirMensagem(String mensagem) {
        JOptionPane.showMessageDialog(this, mensagem, "Mensagem do sistema",
                JOptionPane.ERROR_MESSAGE);
    }

    /**
     * Repinta os componentes.
     */
    public void rePintar() {
        paintComponents(this.getGraphics());
    }

    /**
     * Retorna o usuario logado no sistema.
     * @return Usuario logado no sistema.
     */
    public Usuario getUsuarioLogado() {
        return usuarioLogado;
    }

    /**
     * Main principal.
     * @param args Argumentos.
     */
    public static void main(String[] args) {
        FrameGCP frameGcp = new FrameGCP();
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf."
                    + "nimbus.NimbusLookAndFeel");
            SwingUtilities.updateComponentTreeUI(frameGcp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        frameGcp.setVisible(true);
    }
}